package com.godtree.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.godtree.model.BazhuanyuTask;
import com.godtree.dao.BazhuanyuTaskMapper;
import com.godtree.service.IBazhuanyuTaskService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.godtree.util.bazhuayu.*;
import com.google.common.collect.Lists;
import com.xxl.job.core.context.XxlJobHelper;
import lombok.RequiredArgsConstructor;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.godtree.util.bazhuayu.TokenTools.getToken;

/**
 * <p>
 * 八爪鱼任务表 服务实现类
 * </p>
 *
 * @author lisicheng
 * @since 2022-10-16
 */
@Service
@RequiredArgsConstructor
public class BazhuanyuTaskServiceImpl extends
    ServiceImpl<BazhuanyuTaskMapper, BazhuanyuTask> implements IBazhuanyuTaskService {

  private final MongoTemplate mongoTemplate;

  @Override
  public void createTask() {

    List<String> taskGroup = TaskGroupTools.getTaskGroup();

    XxlJobHelper.log("获取到任务组：{}条", taskGroup.size());

    if (CollUtil.isEmpty(taskGroup)) {
      return;
    }

    List<BazhuanyuTask> taskList = taskGroup.stream().map(TaskTools::getTask)
        .flatMap(Collection::stream)
        .peek(item -> item.setIsSync(StrUtil.startWith(item.getTaskName(), "OK_")))
        .peek(item -> item.setRankId(
            new LinkedList<>(StrUtil.split(item.getTaskName(), "_")).peekLast()))
        .collect(Collectors.toList());

    XxlJobHelper.log("通过任务组获取到任务：{}条", taskList);
    XxlJobHelper.log("正常同步任务：{}",
        taskList.stream().filter(BazhuanyuTask::getIsSync).collect(Collectors.toList()));

    Map<String, Long> dbTaskMap =
        list(Wrappers.<BazhuanyuTask>lambdaQuery()
            .select(BazhuanyuTask::getTaskId, BazhuanyuTask::getId).in(
                BazhuanyuTask::getTaskId,
                taskList.stream().map(BazhuanyuTask::getTaskId).collect(Collectors.toList())))
            .stream().collect(Collectors.toMap(BazhuanyuTask::getTaskId, BazhuanyuTask::getId));

    // 设置id
    taskList.forEach(item -> item.setId(dbTaskMap.get(item.getTaskId())));

    XxlJobHelper.log("新增任务数：{}",
        taskList.stream().filter(item -> item.getId() == null).count());
    XxlJobHelper.log("修改任务数：{}",
        taskList.stream().filter(item -> item.getId() != null).count());

    // 新增或修改
    saveOrUpdateBatch(taskList);
    // 将不存在的任务修改为不同步
    update(Wrappers.<BazhuanyuTask>lambdaUpdate().set(BazhuanyuTask::getIsSync, false).notIn(
        BazhuanyuTask::getTaskId,
        taskList.stream().map(BazhuanyuTask::getTaskId).collect(Collectors.toList())));

  }

  @Override
  public void syncData() {

    List<BazhuanyuTask> taskList = list(
        Wrappers.<BazhuanyuTask>lambdaQuery().eq(BazhuanyuTask::getIsSync, true));

    if (CollUtil.isEmpty(taskList)) {
      XxlJobHelper.log("任务为空");
      return;
    }

    XxlJobHelper.log("任务数：{}", taskList.size());

    for (BazhuanyuTask bazhuanyuTask : taskList) {

      String taskId = bazhuanyuTask.getTaskId();
      // status定义为：运行中 = 0，已停止 = 1，已完成 = 2，待运行 = 3，未执行 = 5
      if (Objects.equals(TaskTools.getTaskStatus(Lists.newArrayList(taskId)).get(taskId), 0)) {
        XxlJobHelper.log("任务id：{}，任务名称：{}。正在运行中，跳过数据同步", taskId,
            bazhuanyuTask.getTaskName());
        continue;
      }

      XxlJobHelper.log("任务id：{}，任务名称：{}。开始同步数据。。。", taskId,
          bazhuanyuTask.getTaskName());
      int count = 0;
      int index = 1;
      while (true) {

        List<Map<String, Object>> list = DataTools.data(taskId);

        if (CollUtil.isEmpty(list)) {
          break;
        }

        count += list.size();
        XxlJobHelper.log("第{}次同步数据条数：{}", index++, list.size());
        mongoTemplate.insert(list, "rank");
        XxlJobHelper.log("同步到mongodb成功");

        UpdateTools.update(taskId, getToken());
        XxlJobHelper.log("标记数据为已导出");

      }

      // 删除数据，不然下次采集的数据会因为重复而拉取不了
      UpdateTools.remove(taskId, getToken());
      XxlJobHelper.log("任务id：{}，任务名称：{}。数据条数：{}", taskId,
          bazhuanyuTask.getTaskName(), count);

    }

  }
}
